﻿// -----------------------------------------------------------------------
// <copyright file="TaskPaneViewModel.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

using System.Threading.Tasks;
using GalaSoft.MvvmLight.Threading;

namespace ClearLines.Stocks.UserInterface
{
   using System;
   using System.Collections.Generic;
   using System.Collections.ObjectModel;
   using System.Linq;
   using System.Text;
   using Domain;
   using GalaSoft.MvvmLight;
   using GalaSoft.MvvmLight.Command;
   using Microsoft.Office.Interop.Excel;
   using Utilities;

   /// <summary>
   /// TODO: Update summary.
   /// </summary>
   public class TaskPaneViewModel : ViewModelBase
   {
      private const string defaultSymbol = "MSFT";

      private readonly ExcelController excelController;

      private string symbolToLoad;
      private readonly RelayCommand loadSymbol;
      private DateTime startDate;
      private DateTime endDate;

      private readonly ObservableCollection<StockHistory> stocks;
      private StockHistory selectedStock;

      private readonly RelayCommand simulateStock;
      private int runs;
      private bool isSimulationRunning;

      public TaskPaneViewModel(ExcelController controller)
      {
         DispatcherHelper.Initialize();

         this.symbolToLoad = defaultSymbol;
         this.stocks = new ObservableCollection<StockHistory>();
         this.excelController = controller;
         this.loadSymbol = new RelayCommand(this.ExecuteLoadSymbol);
         this.endDate = DateTime.Today;
         this.startDate = DateTime.Today.AddYears(-1);

         this.isSimulationRunning = false;
         this.simulateStock = new RelayCommand(this.ExecuteSimulate, this.CanSimulate);
         this.runs = 10000;
      }

      public ObservableCollection<StockHistory> Stocks
      {
         get { return this.stocks; }
      }

      public StockHistory SelectedStock
      {
         get { return this.selectedStock; }
         set
         {
            if (this.selectedStock != value)
            {
               this.selectedStock = value;
               base.RaisePropertyChanged("SelectedStock");
            }
         }
      }

      public string SymbolToLoad
      {
         get { return this.symbolToLoad; }
         set
         {
            if (this.symbolToLoad != value)
            {
               this.symbolToLoad = value;
               base.RaisePropertyChanged("SymbolToLoad");
            }
         }
      }

      public RelayCommand LoadSymbol
      {
         get { return this.loadSymbol; }
      }

      public DateTime StartDate
      {
         get { return this.startDate; }
         set
         {
            if (this.startDate != value)
            {
               this.startDate = value;
               base.RaisePropertyChanged("StartDate");
            }
         }
      }

      public DateTime EndDate
      {
         get { return this.endDate; }
         set
         {
            if (this.endDate != value)
            {
               this.endDate = value;
               base.RaisePropertyChanged("EndDate");
            }
         }
      }

      public RelayCommand SimulateStock
      {
         get { return this.simulateStock; }
      }

      public int Runs
      {
         get { return this.runs; }
         set
         {
            if (this.runs != value)
            {
               this.runs = value;
               base.RaisePropertyChanged("Runs");
            }
         }
      }

      private ExcelController Controller
      {
         get { return this.excelController; }
      }

      private void ExecuteLoadSymbol()
      {
         var history = HistoryReader.Read(this.SymbolToLoad, this.StartDate, this.EndDate);
         this.stocks.Add(history);

         var worksheet = this.Controller.GetWorksheetForSymbol(this.SymbolToLoad);
         HistoryWriter.Write(history, worksheet);

         var chart = this.Controller.GetChartForSymbol(this.SymbolToLoad);
         StockHistoryChart.Write(history, chart);
      }

      public bool IsSimulationRunning
      {
         get { return this.isSimulationRunning; }
         set
         {
            if (this.isSimulationRunning != value)
            {
               this.isSimulationRunning = value;
               base.RaisePropertyChanged("IsSimulationRunning");
            }
         }
      }

      private void ExecuteSimulate()
      {
         var stock = this.SelectedStock;
         if (stock != null)
         {
            Task.Factory.StartNew(
               () =>
                  {
                     DispatcherHelper.CheckBeginInvokeOnUI(() => this.IsSimulationRunning = true);

                     var symbol = stock.Symbol;
                     var densityChart = this.Controller.GetDensityChartForSymbol(symbol);
                     densityChart.Visible = XlSheetVisibility.xlSheetHidden;
                     ValueDistributionChart.Write(stock, 100, this.Runs, densityChart);
                     densityChart.Visible = XlSheetVisibility.xlSheetVisible;

                     DispatcherHelper.CheckBeginInvokeOnUI(() => this.IsSimulationRunning = false);
                  }
               );
         }
      }

      private bool CanSimulate()
      {
         return (this.SelectedStock != null && this.Runs > 0 && !this.IsSimulationRunning);
      }
   }
}
